﻿#include "treeviewwithcustomwidget.h"
#include "ui_treeviewwithcustomwidget.h"

#include <QStandardItemModel>
#include <QStandardItem>
#include <QDebug>
#include <QMouseEvent>
#include <QScrollBar>
#include <QSvgRenderer>

TreeVarDelegate::TreeVarDelegate(QObject *parent)
    :QStyledItemDelegate(parent)
{
    auto pTreeView = qobject_cast<QTreeView*>(parent);
    Q_ASSERT(pTreeView);
}

void TreeVarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    auto d = index.data(Qt::ItemDataRole::UserRole);

    if(d.isValid())
    {
        auto pData = d.value<void*>();
        auto pWidget = (QCheckBox*)pData;
        pWidget->show();
        auto rc = pWidget->geometry();
        auto rc2 = option.rect;
        pWidget->setGeometry(option.rect);
    }
    else
    {
        auto ed = index.siblingAtColumn(0);
        auto d = ed.data(Qt::ItemDataRole::UserRole);
        if(d.isValid())
        {
            auto pData = d.value<void*>();
            auto pWidget = (QCheckBox*)pData;
            if(pWidget->isChecked())
            {
                painter->fillRect(option.rect, QColor("#ebf4ff"));
            }
        }
        QStyledItemDelegate::paint(painter, option, index);
    }

    // QCheckBox box;
    // box.setText("test");
    // painter->save();
    // painter->translate(option.rect.topLeft());
    // box.render(painter);
    // painter->restore();
}

///
/// \brief TreeWarchVarDelegate::updateEditorGeometry
/// 更新代理视图
/// \param editor
/// \param option
/// \param index
///
void TreeVarDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(index);
    if(editor == nullptr)
    {
        return;
    }
    editor->setGeometry(option.rect);
}

QWidget *TreeVarDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    return new TestWidget(parent);
}

void TreeVarDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    int i = 0;
}

CTreeViewWithCustomWidget::CTreeViewWithCustomWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::CTreeViewWithCustomWidget)
{
    ui->setupUi(this);

    // QImage img(":/resources/image/test.svg");
    // QSvgRenderer renderer(QString(":/resources/image/test.svg"));
    // QPixmap pixmap(renderer.defaultSize());
    // QPainter painter(&pixmap);
    // renderer.render(&painter);

    // pixmap.convertFromImage(img);

    // ui->widget->load(QString(":/resources/image/test.svg"));

    InitTreeView();
}

CTreeViewWithCustomWidget::~CTreeViewWithCustomWidget()
{
    delete ui;
}

bool CTreeViewWithCustomWidget::eventFilter(QObject *watched, QEvent *event)
{
    if(event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
        auto pCheckBox = qobject_cast<QCheckBox*>(watched);
        if(pCheckBox)
        {
            //qDebug() << "checkbox :" << event;
            auto ptfLocal = mouseEvent->localPos();
            QPoint ptLocal;
            ptLocal.setX(ptfLocal.x());
            ptLocal.setY(ptfLocal.y());
            auto ptParent = pCheckBox->mapToParent(ptLocal);
            //qDebug() << "checkbox : " << ptParent;
            QMouseEvent newEvent(mouseEvent->type(), ptParent, mouseEvent->screenPos(),
                                 mouseEvent->button(), mouseEvent->buttons(), mouseEvent->modifiers());
            // 因为checkbox挡住了treeview的item，所以鼠标hover checkbox后面的item时接收不到的，导致tree节点未选中
            // 因此拦截到checkbox点击事件后再转发点击事件到treeview上，进而选择相应tree节点
            QApplication::sendEvent(ui->treeView->viewport(), &newEvent);
        }
        else
        {
            //qDebug() << "treeview :" << event;
        }
        // Get the index of the item at the mouse click position
        QModelIndex index = ui->treeView->indexAt(mouseEvent->pos());
        if (index.isValid()) {
            // Create a new mouse press event and send it to the treeView
            QMouseEvent newEvent(mouseEvent->type(), mouseEvent->localPos(), mouseEvent->screenPos(),
                                 mouseEvent->button(), mouseEvent->buttons(), mouseEvent->modifiers());
            // 因为checkbox挡住了treeview的item，所以鼠标hover checkbox后面的item时接收不到的，导致tree节点未选中
            // 因此拦截到checkbox点击事件后再转发点击事件到treeview上，进而选择相应tree节点
            //QApplication::sendEvent(ui->treeView, &newEvent);
        }
    }
    return false;
}

void CTreeViewWithCustomWidget::on_treeView_clicked(const QModelIndex &index)
{
    static int count = 0;
    qDebug() << "tree item click" << count++;
}

void CTreeViewWithCustomWidget::InitTreeView()
{
    static const int ROWS = 1000;
    static const int COLUMNS = 4;

    m_pTreeModel = new QStandardItemModel(ui->treeView);

    m_pTreeModel->setHorizontalHeaderLabels(QStringList()<<""<<"index"<<"title"<<"remark");

    // 创建根节点，抽象Item，并没有实际数据
    QStandardItem* itemRoot = m_pTreeModel->invisibleRootItem();

    // 创建并添加Item的第一个子节点
    QStandardItem* itemTools = new QStandardItem(QStringLiteral("tools"));

    for(int i=0;i<ROWS;i++){
        QList<QStandardItem*> items;
        items << new QStandardItem();
        items << new QStandardItem(QString("%1").arg(i));
        items << new QStandardItem(QString("tool_%1").arg(i+1));
        items << new QStandardItem();
        itemTools->appendRow(items);

        auto pWidget = new QCheckBox("MW100", ui->treeView->viewport());
        auto size = pWidget->sizeHint();
        //pWidget->setStyleSheet("background:#aaaaff");
        pWidget->setContentsMargins(6, 0 ,0, 0);
        pWidget->installEventFilter(this);
        pWidget->hide();

        auto p = items.at(0);
        p->setData(QVariant::fromValue(Qt::red), Qt::BackgroundColorRole);
        connect(pWidget, &QCheckBox::clicked, this, [p](bool b){
            if(b)
            {

            }
        });

        items.at(0)->setData(QVariant::fromValue((void*)pWidget), Qt::ItemDataRole::UserRole);
    }
    itemRoot->appendRow(itemTools);

    ui->treeView->viewport()->installEventFilter(this);
    ui->treeView->setModel(m_pTreeModel);
    ui->treeView->setItemDelegateForColumn(0, new TreeVarDelegate(ui->treeView));
    ui->treeView->setItemDelegateForColumn(1, new TreeVarDelegate(ui->treeView));
    ui->treeView->setHeader(new CheckBoxHeaderView(0, Qt::Horizontal, this));
    auto root = m_pTreeModel->index(0,0);
    QModelIndex index = m_pTreeModel->index(3,0,root);
    ui->treeView->openPersistentEditor(index);
    ui->treeView->expandAll();

    connect(ui->treeView, &QTreeView::collapsed, this, [this](const QModelIndex& index){
        auto item = m_pTreeModel->itemFromIndex(index);
        int count = item->rowCount();
        for(int i=0;i<count;i++)
        {
            auto child = item->child(i, 0);
            auto d = child->data(Qt::ItemDataRole::UserRole);
            if(d.isValid())
            {
                auto pData = d.value<void*>();
                auto pWidget = (QCheckBox*)pData;
                pWidget->hide();
            }
        }
    });

    connect(ui->treeView->verticalScrollBar(), &QScrollBar::valueChanged, this, [this](int arg){
        qDebug() << "vscroll : " << arg;

        auto rcTableViewPort = ui->treeView->viewport()->rect();
        auto rcTopLeft = rcTableViewPort.topLeft();
        auto rcBottomRight = rcTableViewPort.bottomRight();
        auto indexTopLeft = ui->treeView->indexAt(rcTopLeft);
        auto indexBottomRight = ui->treeView->indexAt(rcTopLeft);
        qDebug() <<indexTopLeft;
        ui->treeView->selectionModel()->select(indexTopLeft,QItemSelectionModel::Rows);
        auto idx = ui->treeView->indexAt({0,arg});
        qDebug() << idx.row() << "|||||" << ui->treeView->visualRect(idx);
    });
}

// QWidget* GetTreeItemWidget(QTreeView* pTreeView)
// {
//     static  int count = 1;
//     auto pWidget = new QCheckBox(pTreeView->viewport());
//     pWidget->setText(QString("Test_%1").arg(count++));
//     return pWidget;
// }

void CTreeViewWithCustomWidget::on_pushButton_clicked()
{
    auto index = ui->treeView->currentIndex();
    //m_pTreeModel->removeRows(3,1,m_pTreeModel->index(0,0));

    auto root = m_pTreeModel->index(0,0);
    QModelIndex index2 = m_pTreeModel->index(3,0,root);
    m_pTreeModel->insertRow(index2.row(), root);
    auto index3 = index2.siblingAtRow(index2.row()+1);
    auto pWidget = ui->treeView->indexWidget(index3);
    int i = 0;
    i++;
    //m_pTreeModel->setData(index2, "", Qt::DisplayRole);

    //ui->treeView->openPersistentEditor(index2);
}

